<?php


namespace App\Services;

use App\Models\PackVideo;
use App\Models\PapperVideo;
use App\Models\Video;
use App\Utils\Code;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class VideoService extends BaseService
{
    /**
     * 创建数据
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function store(array $params) {
        if (!$this->checkParams($params)){
            throw new \Exception('请求参数验证不通过', Code::PARAMETER_ERROR);
        }
        if (Video::where('name', $params['name'])->exists()) {
            return '名称重复';
            throw new \Exception('名称重复', Code::PARAMETER_ERROR);
        }
        return DB::transaction(function () use ($params){
            $model = new Video();
            $model->name = $params['name'];
            $model->path = $params['path'];
            $model->type = 1;
            if (isset($params['type']) && $params['type']) {
                $model->type = $params['type'];
            }
            if (isset($params['folder_id']) && $params['folder_id']) {
                $model->folder_id = $params['folder_id'];
            } else {
                $model->folder_id = 0;
            }
            $model->save();
            if (isset($params['tags']) && is_array($params['tags'])){
                $model->tags()->sync($params['tags']);
            }
            return true;
        });
    }

    public function check(array $params) {
        if (!isset($params['name']) || !$params['name']) {
            throw new \Exception('名称不能为空', Code::PARAMETER_ERROR);
        }
        if (Video::where('name', $params['name'])->exists()) {
            return '名称重复';
        }
        return true;
    }

    /**
     * 数据信息
     * @param $id
     * @param bool $simple
     * @param bool $abnormal
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function show($id, $abnormal = true) {
        $model = Video::where('id', $id)->with(['tags', 'folder'])->first();
        if (!$model && $abnormal){
            throw new \Exception('不存在的ID', Code::EMPTY_DATA);
        }
        return $model;
    }

    /**
     * 更新数据
     * @param $id
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     * @throws \Exception
     */
    public function update($id, array $params) {
        if (!$this->checkParams($params, true)){
            throw new \Exception('请求参数验证不通过', Code::PARAMETER_ERROR);
        }
        return DB::transaction(function () use ($id, $params){
            $model = $this->show($id);
            if (isset($params['name']) && $params['name']) {
                $model->name = $params['name'];
            }
            if (isset($params['path']) && $params['path']) {
                $model->path = $params['path'];
            }
            if (isset($params['folder_id']) && $params['folder_id']) {
                $model->folder_id = $params['folder_id'];
            } else {
                $model->folder_id = 0;
            }
            if (isset($params['tags'])){
                if (is_array($params['tags']) && $params['tags']) {
                    $model->tags()->detach();
                    $model->tags()->sync($params['tags']);
                } else {
                    $model->tags()->detach();
                }
            }
            $model->save();
            return $this->show($id);
        });
    }
    
    public function split($id, array $params) {
        if (!isset($params['second']) && !$params['second']) {
            throw new \Exception('请输入要分段的秒数', Code::PARAMETER_ERROR);
        }
        $model = $this->show($id);
        $qiniuService = new QiniuService();
        return $qiniuService->segmentVideo($model->path, $params['second']);
    }
    
    /**
     * 批量修改
     */
    public function updateAll(array $params) {
        if (!isset($params['ids']) || !is_array($params['ids'])) {
            throw new \Exception('ids不能为空', Code::PARAMETER_ERROR);
        }
        // if (!isset($params['folder_id']) || !$params['folder_id']) {
        //     throw new \Exception('文件夹不能为空', Code::PARAMETER_ERROR);
        // }
        return DB::transaction(function () use ($params) {
            $ids = $params['ids'];
            $folder_id = !empty($params['folder_id']) ? $params['folder_id'] : 0;
            $tags = !empty($params['tags']) ? $params['tags'] : [];
            foreach ($ids as $id) {
                $model = Video::find($id);
                if ($model) {
                    if ($folder_id > 0) {
                        $model->folder_id = $folder_id;
                    }
                    $model->tags()->detach();
                    $model->tags()->sync($tags);
                    $model->save();
                }
            }
            return true;
        });
    }

    /**
     * 删除数据
     * @param $id
     * @return mixed
     * @throws \Exception
     */
    public function destroy(array $ids = []) {
        if (!$this::$admin) {
            throw new \Exception('你没有权限进行删除', Code::LACK_OF_CONDITIONS);
        }
        return DB::transaction(function () use ($ids) {
            return Video::whereIn('id', $ids)->delete();
        });
    }

    /**
     * 数据分页
     * @param array $params
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function lists(array $params = []) {
        if (isset($params['is_simple']) && $params['is_simple'] === 1) {
            $model = Video::select('id');
        } else {
            $model = Video::with(['tags', 'folder']);
        }
        if (isset($params['papper_id']) && is_numeric($params['papper_id'])) {
            // $builder = PapperVideo::where('papper_id', $params['papper_id'])->pluck('video_id');
            // $model = $model->whereIn('id', $builder);
            $model = $model->leftJoin('papper_video', 'papper_video.video_id', '=', 'videos.id')->select(['videos.*']);
            $model = $model->where('papper_video.papper_id', $params['papper_id'])->orderBy('papper_video.sort', 'asc');
        }
        if (isset($params['folder_id']) && is_numeric($params['folder_id'])) {
            $model = $model->where('folder_id', $params['folder_id']);
        }
        if (isset($params['media_type']) && is_numeric($params['media_type'])) {
            $model = $model->where('type', $params['media_type']);
        } else {
            $model = $model->where('type', 1);
        }
        if (isset($params['pack_id']) && is_numeric($params['pack_id'])) {
            $builder = PackVideo::where('pack_id', $params['pack_id'])->pluck('video_id');
            $model = $model->whereIn('id', $builder);
        }
        if (isset($params['name']) && $params['name']) {
            $model = $model->where('name', 'like', '%'.$params['name'].'%');
        }
        if (isset($params['status'])) {
            if ($params['status'] == 'unused') {
                $model = $model->where('use_count', '=', 0);
            } elseif ($params['status'] == 'used') {
                $model = $model->where('use_count', '>', 0);
            }
        }
        if (isset($params['type']) && $params['type'] == 'none') {
            $model = $model->whereDoesntHave('tags');
        } elseif (isset($params['type']) && $params['tags']) {
            $tagIds = explode(',', $params['tags']);
            if (count($tagIds) > 0) {
                if ($params['type'] == 'single') {
                    $model = $model->whereHas('tags', function ($query) use ($tagIds) {
                        $query->whereIn('tag_id', $tagIds);
                    });
                } elseif ($params['type'] == 'all') {
                    $model = $model->whereHas('tags', function ($query) use ($tagIds) {
                        $query->whereIn('tag_id', $tagIds);
                    }, '=', count($tagIds));
                }
            }
        }
        if (isset($params['created_at']) && $params['created_at']) {
            $params['created_at'] = explode(',', $params['created_at']);
            $model = $model->where('created_at', '>=', $params['created_at'][0]);
            $model = $model->where('created_at', '<=', $params['created_at'][1]);
        }
        if (isset($params['order']) && $params['order'] == 'name') {
            $model = $model->orderBy('name', 'asc');
        }
        $lists = $model->orderBy('id', 'desc')->paginate(isset($params['per_page']) ? (int)$params['per_page'] : 15);
        return $lists;
    }

    /**
     * 验证参数
     * @param array $params
     * @param bool $isUpdate
     * @return array
     * @throws \Exception
     */
    private function checkParams(array $params, $isUpdate = false){
        $rules = [
            'name' => ['bail', 'required', 'string', 'between:1,50'],
            'path' => ['bail', 'required', 'string', 'between:1,250'],
            'folder_id' => ['bail', 'nullable', 'integer']
        ];
        if ($isUpdate){
            // 删除必选条件
            foreach ($rules as $field => &$rule){
                if (isset($rule[1]) && $rule[1] == 'required') {
                    unset($rule[1]);
                }
            }
        }
        $validator = Validator::make($params, $rules, [], [
            'name' => '名称',
            'path' => '路径',
            'folder_id' => '文件夹ID'
        ]);
        if ($validator->fails()) {
            throw new \Exception($validator->errors()->first(), Code::PARAMETER_ERROR);
        }
        return $params;
    }
}
